package com.som.service.excel.data3.state;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.som.bean.data3.IpAddressInfo;
import com.som.bean.data3.IpMaskInfo;
import com.som.bean.data3.IpSectionInfo;
import com.som.util.IpAddressUtil;

/**
 * 将IP段的形式数据转换为其他格式的数据
 * 
 * @author liujun
 * @date 2016年4月12日
 * @verion 0.0.1
 */
public class ParseIpSectionStateImp implements ParseStateInf<List<IpSectionInfo>>
{

	public List<IpAddressInfo> parseIp(List<IpSectionInfo> param)
	{
		if (null != param && !param.isEmpty())
		{
			List<IpAddressInfo> result = new ArrayList<IpAddressInfo>();

			IpAddressInfo ipAddres = null;

			List<String> ipList = null;

			for (IpSectionInfo ipSectionInfo : param)
			{
				// 如果首地址与尾地址都不为空，转化为IP信息
				if (!StringUtils.isEmpty(ipSectionInfo.getIpaddress()) && !StringUtils.isEmpty(ipSectionInfo.getIpEnd()))
				{
					// 取得IP段内所有信息
					ipList = IpAddressUtil.getIpListBySecation(ipSectionInfo.getIpaddress(), ipSectionInfo.getIpEnd());

					for (String ipAddr : ipList)
					{
						ipAddres = new IpAddressInfo();
						ipAddres.setIpaddress(ipAddr);
						ipAddres.setMsginfo(ipSectionInfo.getMsginfo());
						result.add(ipAddres);
					}
				} else
				{
					ipAddres = new IpAddressInfo();
					ipAddres.setIpaddress(ipSectionInfo.getIpaddress());
					ipAddres.setMsginfo(ipSectionInfo.getMsginfo());
					result.add(ipAddres);
				}

			}

			return result;
		}

		return null;
	}

	public List<IpSectionInfo> parseIpSection(List<IpSectionInfo> param)
	{
		return param;
	}

	/**
	 * 进行IP段转换为掩码的程序
	 */
	public List<IpMaskInfo> parseIpMask(List<IpSectionInfo> param)
	{

		if (null != param && !param.isEmpty())
		{
			List<IpMaskInfo> resut = new ArrayList<IpMaskInfo>();

			IpMaskInfo mask = null;

			for (IpSectionInfo ipSectionInfo : param)
			{
				// 得到IP地址个数
				int iPnum = this.getIpNum(ipSectionInfo.getIpaddress(), ipSectionInfo.getIpEnd());

				// 检查IP是否能够被2除尽,结果为1
				boolean divRsp = this.divisionTwo(iPnum);

				// 如果能够除尽，继续检查，
				if (divRsp)
				{
					// 得到尾地址被2整除的资料
					int endNum = Integer.parseInt(ipSectionInfo.getIpEnd().substring(ipSectionInfo.getIpEnd().lastIndexOf(".") + 1));
					// 记录下整除的次数
					int countDivNum = this.countdivisionTwo(endNum);

					// 2的X次方和前面的IP地址个数比大小
					int value = (int) Math.pow(2, countDivNum);

					// 如果2的X次方比ip地址个数小
					if (value < endNum)
					{
						mask = new IpMaskInfo();
						mask.setIpMask(ipSectionInfo.getIpaddress());
						mask.setMsgInfo(ipSectionInfo.getMsginfo());
						resut.add(mask);
					}
					// 进行计算掩码
					else
					{
						// 再以IP地址个数,计算出以2为底的指数
						int ipNumDiv = this.countdivisionTwo(iPnum);

						// 得到掩码信息
						int maskNum = 32 - ipNumDiv;

						mask = new IpMaskInfo();
						mask.setIpMask(ipSectionInfo.getIpaddress() + "/" + maskNum);
						mask.setMsgInfo(ipSectionInfo.getMsginfo());
						resut.add(mask);

					}
				}
				// 否则，则记录下首地址输出即可
				else
				{
					mask = new IpMaskInfo();
					mask.setIpMask(ipSectionInfo.getIpaddress());
					mask.setMsgInfo(ipSectionInfo.getMsginfo());
					resut.add(mask);
				}

			}

			return resut;
		}

		return null;
	}

	/**
	 * 得到IP个数
	 * 
	 * @param startIP
	 *            ip段开始 IP
	 * @param endIP
	 *            ip段结束 IP
	 * @return IP的个数
	 */
	private int getIpNum(String startIP, String endIP)
	{

		if (!StringUtils.isEmpty(startIP) && !StringUtils.isEmpty(endIP))
		{
			startIP = startIP.trim();
			endIP = endIP.trim();
			int startIpNum = Integer.parseInt(startIP.substring(startIP.lastIndexOf(".") + 1));
			int endNum = Integer.parseInt(endIP.substring(endIP.lastIndexOf(".") + 1));

			return endNum - startIpNum + 1;

		}
		return 0;
	}

	/**
	 * Ip个数除2，能否被人除尽为1
	 * 
	 * @param num
	 *            IP地址个数
	 * @return true 代表能够被2除尽，有转掩码的可能
	 */
	public boolean divisionTwo(int num)
	{
		// 1,首先检查除以2是否有余数
		int divRsp = num;

		while (divRsp > 0)
		{
			if (divRsp % 2 == 0)
			{
				divRsp = divRsp / 2;

				if (divRsp == 1)
				{
					return true;
				}
			} else if (divRsp % 2 == 1)
			{
				return false;
			}

		}

		return false;
	}

	/**
	 * 统计地址能被2整除的次数
	 * 
	 * @param endIP
	 *            尾地址
	 * @return 被2整除的次数
	 */
	public int countdivisionTwo(int endNum)
	{

		int result = 0;

		int divRsp = endNum;

		// 记录下能被2整除的次数
		while (divRsp > 0)
		{
			if (divRsp % 2 == 0)
			{
				divRsp = divRsp / 2;

				result = result + 1;

				if (divRsp == 1)
				{
					divRsp = 0;
				}
			}
			// 如果当前数字有余数，则不再计算
			else if (divRsp % 2 == 1)
			{
				divRsp = 0;
			}
		}

		return result;
	}

	public static void main(String[] args)
	{
		// ParseIpSectionStateImp mask = new ParseIpSectionStateImp();

		// boolean rsp = mask.divisionTwo(32);
		// System.out.println(rsp);

		// int countDiv = mask.countdivisionTwo(16);
		// System.out.println("countDiv:" + countDiv);

		// System.out.println(Math.pow(2, 3));
	}

}
